package middleware

import (
	"net/http"
	"strings"
	"wms/pkg/logger"
	"wms/pkg/utils"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// JWTAuthMiddleware JWT认证中间件
func JWTAuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		logger.Info("开始JWT认证中间件处理")
		
		// 从请求头获取token
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			logger.Warn("请求头中Authorization为空")
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "请求头中auth为空",
			})
			c.Abort()
			return
		}

		logger.Info("获取到Authorization头", zap.String("header", authHeader))

		// 按空格分割
		parts := strings.SplitN(authHeader, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			logger.Warn("Authorization头格式错误", zap.String("header", authHeader))
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "请求头中auth格式有误",
			})
			c.Abort()
			return
		}

		logger.Info("Bearer前缀验证通过", zap.String("token部分", parts[1][:10]+"..."))

		// 记录使用的密钥
		secretKey := utils.GetJWTSecretKey()
		logger.Info("当前使用的JWT密钥", zap.String("secretKey", secretKey[:3]+"..."))

		// 使用utils包的ParseToken函数解析JWT
		claims, err := utils.ParseToken(parts[1])
		if err != nil {
			logger.Error("JWT解析失败", 
				zap.Error(err), 
				zap.String("token", parts[1]), 
				zap.String("secretKey", secretKey))
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "无效的Token",
			})
			c.Abort()
			return
		}

		logger.Info("JWT解析成功", 
			zap.Uint("userID", claims.UserID),
			zap.String("username", claims.Username),
			zap.Time("过期时间", claims.ExpiresAt.Time))

		// 验证token
		// 将当前请求的用户信息保存到请求的上下文c上
		c.Set("userID", claims.UserID)       // 用于用户标识
		c.Set("username", claims.Username)   // 用户名
		c.Set("roleID", claims.RoleID)       // 角色ID
		
		logger.Info("JWT认证成功，请求继续")
		c.Next()
	}
}

// CORSMiddleware 跨域中间件
func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}
